package es.deusto.programacionIV.calculator.console;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import es.deusto.programacionIV.calculator.model.CalculatorWithDataSource;
import es.deusto.programacionIV.calculator.model.Operation;
import es.deusto.programacionIV.calculator.model.OperationType;
import es.deusto.programacionIV.utils.FileUtils;
import es.deusto.programacionIV.utils.JarUtils;
import es.deusto.programacionIV.utils.SystemInUtils;

/**
 * This class represents the main program of a calculator.
 * The sixth version of the calculator (v0.6) is the sixth iteration to show that using multiple jars is a great 
 * opportunity to create a completely independent/modular solution.
 * 
 * @author Iker Jamardo Zugaza
 *
 */
public class Main 
{
	public static final String OPERATION_TYPES_JARS_PATH_CONFIGURATION_FILE_PATH = "OperationTypeJarFilesPathConfiguration.txt";
	public static final String OPERATION_TYPES_CONFIGURATION_FILE_PATH = "OperationTypesConfiguration.txt";
	public static final String OPERATION_DATA_SOURCE_CONFIGURATION_FILE_PATH = "OperationDataSourceJarFilePathConfiguration.txt";
	
	private static void showMenu(String[] operationTypeNames)
	{	
		// Show the menu.
		System.out.println("Calculator v0.6");
		for (int i = 0; i < operationTypeNames.length; i++)
		{
			System.out.println((i + 1) + ".- " + operationTypeNames[i]);
		}
		System.out.println((operationTypeNames.length + 1) + ".- List of all done operations");
		System.out.println((operationTypeNames.length + 2) + ".- Refresh the operation types");
		System.out.println((operationTypeNames.length + 3) + ".- Exit");
	}
	
	public static void main(String[] args) throws Exception 
	{
		String[] lines = null;
		
		// Read the operation type jar files directory path from the configuration TXT file.
		lines = FileUtils.readLinesFromTXTFile(OPERATION_TYPES_JARS_PATH_CONFIGURATION_FILE_PATH);
		String operationTypeJarFilesDirectoryPath = lines[0];
		
		// Read the operation data source jar file path from the configuration TXT file.
		lines = FileUtils.readLinesFromTXTFile(OPERATION_DATA_SOURCE_CONFIGURATION_FILE_PATH);
		String operationDataSourceJarFilePath = lines[0];

		// Create and initialize the calculator
		CalculatorWithDataSource calculatorWithDataSource = new CalculatorWithDataSource();
		calculatorWithDataSource.init(operationTypeJarFilesDirectoryPath, OPERATION_TYPES_CONFIGURATION_FILE_PATH, operationDataSourceJarFilePath);
		
		String[] operationTypeNames = calculatorWithDataSource.getOperationTypeNames();
		
		try
		{
			int option = 0;
			int exitOption = 0;
			do
			{
				exitOption = operationTypeNames.length + 3;
				showMenu(operationTypeNames);
				option = SystemInUtils.readInt(1, operationTypeNames.length + 3, "Option: ");
				// If the option is a integer between 1 and 4, it's an operation.
				if (option >= 1 && option <= (operationTypeNames.length))
				{
					calculatorWithDataSource.setOperationTypeIndex(option - 1);
					// Use a loop to query for the operands.
					for (int i = 1; i < 3; i++)
					{
						boolean correct = false;
						do
						{
							try
							{
								float operand = SystemInUtils.readFloat("Introduce the operand " + i + ": ");
								switch(i)
								{
								case 1:
									calculatorWithDataSource.setOperand1(operand);
									break;
								case 2:
									calculatorWithDataSource.setOperand2(operand);
									break;
								}
								correct = true;
							}
							catch(IllegalArgumentException e)
							{
								System.err.println("ERROR: " + e.getMessage());
							}
						}
						while(!correct);
					}
					try
					{
						calculatorWithDataSource.calculate();
						System.out.println(calculatorWithDataSource.getOperationToString());
					}
					catch(Exception e)
					{
						System.err.println(e.getMessage());
					}
				}
				else if (option == operationTypeNames.length + 1)
				{
					System.out.println("Listing done operations:");
					Collection<Operation> operations = calculatorWithDataSource.getAllCalculatedOperations();
					for (Operation operation: operations)
					{
						System.out.println(operation);
					}
				}
				else if (option == operationTypeNames.length + 2)
				{
					System.out.println("Refreshing the operation types...");
					calculatorWithDataSource.end();
					lines = FileUtils.readLinesFromTXTFile(OPERATION_DATA_SOURCE_CONFIGURATION_FILE_PATH);
					operationDataSourceJarFilePath = lines[0];
					calculatorWithDataSource.init(operationTypeJarFilesDirectoryPath, OPERATION_TYPES_CONFIGURATION_FILE_PATH, operationDataSourceJarFilePath);
					operationTypeNames = calculatorWithDataSource.getOperationTypeNames();
				}
			}
			while(option != exitOption);
		}
		catch(IOException e)
		{
			System.err.println("ERROR: There has been a severe hadware failure when trying to communicate with the keyboard.");
		}
	}
}
